package com.yunkss.eftool.crypto.operator;

import com.yunkss.eftool.crypto.key.CisCodec;
import com.yunkss.eftool.crypto.params.SmProvider;
import org.bouncycastle.crypto.digests.SM3Digest;
import org.bouncycastle.crypto.macs.HMac;
import org.bouncycastle.crypto.params.KeyParameter;
import org.springframework.stereotype.Component;

import java.util.Arrays;

/**
 * @author csx
 * @date 2022/2/18 8:47
 * @desc
 */

@Component
public class EftoolSM3Operator extends SmProvider {
    public EftoolSM3Operator() {
    }

    private byte[] digest(byte[] data) {
        SM3Digest digest = new SM3Digest();
        digest.update(data, 0, data.length);
        byte[] hash = new byte[digest.getDigestSize()];
        digest.doFinal(hash, 0);
        return hash;
    }

    public String digest(String raw) {
        byte[] bytes = raw.getBytes();
        byte[] digest = this.digest(bytes);
        return CisCodec.encodeToHexString(digest);
    }

    private boolean verify(byte[] data, byte[] sm3Digest) {
        byte[] newHash = this.digest(data);
        return Arrays.equals(newHash, sm3Digest);
    }

    public boolean verify(String data, String sm3DigestHex) {
        byte[] bytes = data.getBytes();
        byte[] newHash = this.digest(bytes);
        return Arrays.equals(newHash, CisCodec.decodeFromHexString(sm3DigestHex));
    }

    private byte[] hmac(byte[] key, byte[] data) {
        KeyParameter keyParameter = new KeyParameter(key);
        SM3Digest digest = new SM3Digest();
        HMac mac = new HMac(digest);
        mac.init(keyParameter);
        mac.update(data, 0, data.length);
        byte[] result = new byte[mac.getMacSize()];
        mac.doFinal(result, 0);
        return result;
    }

    public String hmac(String key, String data) {
        byte[] keyBytes = key.getBytes();
        byte[] dataBytes = data.getBytes();
        byte[] hmac = this.hmac(keyBytes, dataBytes);
        return CisCodec.encodeToHexString(hmac);
    }
}
